#include "shutdown.h"

rotate_speed_c rev;
sem_t poll_get_sem;

rotate_speed_c::
rotate_speed_c()
{
	gpio_fd = -1;
	rising_count = 0;
	speed_test_tid = -1;
}

 
rotate_speed_c::
~rotate_speed_c()
{}

int 
rotate_speed_c::
init_gpio(int *fd)
{
	int ret = system("echo 30> /sys/class/gpio/unexport");
	*fd = open(SYSFS_LED_EXPORT, O_WRONLY);
	if(*fd == -1)
	{
		printf("Open export failed.\n");
		return -1;
	}
	
	ret = write(*fd, SYSFS_LED_EXPORT_VAL, sizeof(SYSFS_LED_EXPORT_VAL));
	if(ret < 0)
	{
		perror("write");
	}
	close(*fd);
	
	/* set gpio158 direction */
	*fd = open(SYSFS_LED_DIR, O_WRONLY);
	if(*fd == -1)
	{
		printf("Open gpio diretion failed.\n");
		return -1;
	}
	ret = write(*fd, SYSFS_LED_DIR_VAL, sizeof(SYSFS_LED_DIR_VAL));
	if(ret < 0)
	{
		perror("write");
	}
	close(*fd);
	
	/* open gpio158 value file to write */
	*fd = open(SYSFS_LED_EDGE, O_WRONLY);
	if(*fd == -1)
	{
		printf("Open gpio edge failed.\n");
		return -1;
	}
	ret = write(*fd, SYSFS_LED_EDGE_VAL, sizeof(SYSFS_LED_EDGE_VAL));
	if(ret < 0)
	{
		perror("write");
	}
	close(*fd);
	return 0;
}

void 
rotate_speed_c:: 
receive_gpio_rising_thread_func(void)
{
	int ret = 0;
	char value;
	sigset_t sigset;
	sigemptyset(&sigset);
	sigaddset(&sigset, SIGALRM);
	sigset_t oldset; 
	
	fds[0].fd = gpio_fd;
	fds[0].events = POLLPRI;
	ret = sem_init(&poll_get_sem, 0, 1);
	
	if (sigprocmask (SIG_SETMASK, &sigset, &oldset) == -1)
    {
        perror ("sigprocmask");
    }
	
	while(1)
	{
		
		printf("wait.\n");
		sem_wait(&poll_get_sem);

		printf("poll start\n");
		ret = poll(fds, 1, -1);
		if(ret == -1)
		{
			perror("poll failed");
			continue;
		}
		
		if(fds[0].revents & POLLPRI)
		{
			ret = lseek(gpio_fd, 0 ,SEEK_SET);
			if(ret == -1)
			{
				printf("read value failed.\n");
			}
		}
	
		sleep(2);
	
		ret = read(gpio_fd, &value, 1);
		if(ret == -1)
		{
			printf("read value failed.\n");
		}
		if(value > 48)
		{
			printf("ready shutdown: %c\n", value);
			sleep(1);
			if(value > 48)
			{
				printf("shutdown: %c\n", value);
				for(int i = 0;i < 10; i++)
				{
					ret = system("echo 22> /sys/class/gpio/export");
					ret = system("echo out > /sys/class/gpio/gpio22/direction");		
					ret = system("echo 1 > /sys/class/gpio/gpio22/value");
					usleep(100000);
					ret = system("echo 0 > /sys/class/gpio/gpio22/value");
					usleep(100000);
				}
				ret = system("shutdown -h now");
			}
		}
		
		ret = lseek(gpio_fd, 0 ,SEEK_SET);
		if(ret == -1)
		{
			printf("read value failed.\n");
		}
			//printf("value = %d,rising_count = %d.\n",value, rising_count);
		sem_post(&poll_get_sem);
	}
	
}

int
rotate_speed_c::
setup(void)
{
	int ret = 0;
	char value;
	
	init_gpio(&gpio_fd);
	
	gpio_fd = open(SYSFS_LED_VAL, O_RDONLY);
	if(gpio_fd == -1)
	{
		printf("Open gpio value failed.\n");
		return -1;
	}
	
	ret = lseek(gpio_fd, 0, SEEK_SET);
	if(ret == -1)
	{
		printf("lseek failed.\n");
	}

	ret = read(gpio_fd, &value, 1);
	if(ret == -1)
	{
		printf("read value failed.\n");
	}
	
	if((ret = pthread_create(&speed_test_tid, NULL, &start_receive_gpio_rising_thread, this))< 0)
	{
		printf("Create receive gp160 rising Thread Error. %d\n", ret);
		return -1;
	}	
	return 0;
}

void
rotate_speed_c::
exit(void)
{
	pthread_cancel(speed_test_tid);
	close(gpio_fd);
}

void*
start_receive_gpio_rising_thread(void *args)
{
	// takes an autopilot object argument
	rotate_speed_c *rotate_speed = (rotate_speed_c *)args;

	// run the object's read thread
	rotate_speed->receive_gpio_rising_thread_func();

	// done!
	return NULL;
}

int main(void)
{
	int ret = rev.setup();
	if(ret == -1)
	{
		printf("rotate_speed setup error\n");
	}
	pthread_join(rev.speed_test_tid ,NULL);
}
